<?php
/**
 * SEF component for Joomla! 1.5
 *
 * @author      ARTIO s.r.o.
 * @copyright   ARTIO s.r.o., http://www.artio.cz
 * @package     JoomSEF
 * @version     3.1.0
 */

// Security check to ensure this file is being included by a parent file.
defined('_JEXEC') or die('Restricted access');

JLoader::register('SEFConfig', JPATH_ADMINISTRATOR.DS.'components'.DS.'com_sef'.DS.'classes'.DS.'config.php');

class plgSystemJoomsef extends JPlugin
{
    var $linksDivs = array();

    function plgSystemJoomsef( &$subject )
    {
        parent::__construct($subject);

        // load plugin parameters
        $this->_plugin = & JPluginHelper::getPlugin('system', 'joomsef');
        $this->_params = new JParameter($this->_plugin->params);
    }

    function onAfterInitialise()
    {
        global $mainframe;

        // Do not run plugin in administration area
        if ($mainframe->isAdmin()) return true;

        // Do not run plugin if SEF is disabled
        $config =& JFactory::getConfig();
        if (!$config->getValue('sef')) return true;

        // check if joomsef is enabled
        $sefConfig =& SEFConfig::getConfig();

        if ($sefConfig->enabled) {
            if ($sefConfig->wwwHandling != _COM_SEF_WWW_NONE) {
                // Handle www and non-www domain
                $uri  =& JURI::getInstance();
                $host =& $uri->getHost();
                $redirect = false;

                if ($sefConfig->wwwHandling == _COM_SEF_WWW_USE_WWW && strpos($host, 'www.') !== 0) {
                    // host must begin with www.
                    $redirect = true;
                    $uri->setHost('www.'.$host);
                }
                else if ($sefConfig->wwwHandling == _COM_SEF_WWW_USE_NONWWW && strpos($host, 'www.') === 0) {
                    // host must not begin with www.
                    $redirect = true;
                    $uri->setHost(substr($host, 4));
                }

                // Redirect if needed
                if ($redirect) {
                    $url = $uri->toString();
                    header('Location: ' . $url, true, 301);
                    jexit();
                }

            }

            $router =& $mainframe->getRouter();

            // Store the router for later use
            $mainframe->set('sef.global.jrouter', $router);

            require_once( JPATH_ROOT.DS.'components'.DS.'com_sef'.DS.'sef.router.php' );
            $router = new JRouterJoomsef();
        }

        return true;
    }
    /*
    function onAfterRoute()
    {
    global $mainframe;

    // Do not run plugin in administration area
    if ($mainframe->isAdmin()) return true;

    // Do not run plugin if SEF is disabled
    $config =& JFactory::getConfig();
    if (!$config->getValue('sef')) return true;

    // check if joomsef is enabled
    $sefConfig =& SEFConfig::getConfig();

    if (!$sefConfig->enabled) return true;

    return true;
    }
    */
    function onPrepareContent(&$row, &$params, $page=0) {
        global $mainframe;

        // Do not run plugin in administration area
        if ($mainframe->isAdmin()) return;

        // Do not run plugin if SEF is disabled
        $config =& JFactory::getConfig();
        if (!$config->getValue('sef')) return;

        // check if joomsef is enabled
        $sefConfig =& SEFConfig::getConfig();
        if (!$sefConfig->enabled) return;

        // Nofollow tag
        $this->_noFollow($row->text);

        // Word links
        $this->_wordLinks($row->text);

        return;
    }

    function onAfterDispatch()
    {
        global $mainframe;

        // Do not run plugin in administration area
        if ($mainframe->isAdmin()) return true;

        // Check if SEF and plugin are enabled
        if (!class_exists('JoomSEF') || !JoomSEF::enabled($this)) return true;

        // Check page base href value
        $this->_checkBaseHref();

        // Do not run plugin if metadata generation is disabled
        $sefConfig =& SEFConfig::getConfig();
        if ($sefConfig->enable_metadata) {
            // generate page title
            $this->_checkSefTitle();

            // generate page metadata
            $this->_generateMeta();
        }
        
        // Generate the links javascript
        $this->_generateScript();
        
        return true;
    }
    
    function _generateMeta()
    {
        global $mainframe;

        $document = & JFactory::getDocument();
        $sefConfig =& SEFConfig::getConfig();

        $rewriteKeywords    = $sefConfig->rewrite_keywords;
        $rewriteDescription = $sefConfig->rewrite_description;

        $metadesc       = str_replace('"', '&quot;', $mainframe->get('sef.meta.desc'));
        $metakey        = str_replace('"', '&quot;', $mainframe->get('sef.meta.key'));
        $metalang       = str_replace('"', '&quot;', $mainframe->get('sef.meta.lang'));
        $metarobots     = str_replace('"', '&quot;', $mainframe->get('sef.meta.robots'));
        $metagoogle     = str_replace('"', '&quot;', $mainframe->get('sef.meta.google'));
        $canonicallink  = str_replace('"', '&quot;', $mainframe->get('sef.link.canonical'));
        $generator      = str_replace('"', '&quot;', $sefConfig->tag_generator);
        $googlekey      = str_replace('"', '&quot;', $sefConfig->tag_googlekey);
        $livekey        = str_replace('"', '&quot;', $sefConfig->tag_livekey);
        $yahookey       = str_replace('"', '&quot;', $sefConfig->tag_yahookey);

        // description metatag
        if (!empty($metadesc)) {
            $oldDesc = $document->getDescription();
            $rewrite = (($rewriteDescription == '1') || ($oldDesc == ''));

            if ($rewrite) {
                $document->setDescription($metadesc);
            } else {
                $document->setDescription($metadesc . ', ' . $oldDesc);
            }
        }

        // keywords metatag
        if (!empty($metakey)) {
            $oldKey = $document->getMetaData('keywords');
            $rewrite = (($rewriteKeywords == '1') || ($oldKey == ''));

            if ($rewrite) {
                $document->setMetaData('keywords', $metakey);
            } else {
                $document->setMetaData('keywords', $metakey . ', ' . $oldKey);
            }
        }

        if (!empty($metalang))   $document->setMetaData('lang', $metalang);
        if (!empty($metarobots)) $document->setMetaData('robots', $metarobots);
        if (!empty($metagoogle)) $document->setMetaData('google', $metagoogle);
        if (!empty($generator))  $document->setGenerator($generator);
        if (!empty($googlekey))  $document->setMetaData('google-site-verification', $googlekey);
        if (!empty($livekey))    $document->setMetaData('msvalidate.01', $livekey);
        if (!empty($yahookey))   $document->setMetaData('y_key', $yahookey);

        // Custom meta tags
        if (is_array($sefConfig->customMetaTags)) {
            foreach($sefConfig->customMetaTags as $name => $content) {
                $content = str_replace('"', '&quot;', $content);
                $document->setMetaData($name, $content);
            }
        }

        if (method_exists($document, 'addHeadLink')) {
            if (!empty($canonicallink)) $document->addHeadLink($canonicallink, 'canonical');
        }
    }

    function _checkSefTitle()
    {
        global $mainframe;

        $document = &JFactory::getDocument();
        $config = &JFactory::getConfig();
        $sefConfig =& SEFConfig::getConfig();

        $sitename     = $config->getValue('sitename');
        $useMetaTitle = $config->getValue('MetaTitle');
        $preferTitle = $sefConfig->prefer_joomsef_title;
        $useSitename = $sefConfig->use_sitename;
        $sitenameSep = ' '.trim($sefConfig->sitename_sep).' ';
        $preventDupl = $sefConfig->prevent_dupl;

        if ($sitenameSep == '  ') $sitenameSep = ' ';

        // Page title
        $pageTitle = $mainframe->get('sef.meta.title');

        if (empty($pageTitle)) {
            $pageTitle = $document->getTitle();

            // Dave: replaced regular expression as it was causing problems
            //       with site names like [ index-i.cz ] with str_replace
            // Dave: 3.2.9 fix - added check for !empty($sitename) - was causing
            //       problems with empty site names

            /*$pageSep = '( - |'.$sitenameSep.')';
            if (preg_match('/('.$GLOBALS['mosConfig_sitename'].$pageSep.')?(.*)?/', $pageTitle, $matches) > 0) {
            $pageTitle = strtr($pageTitle, array($matches[1] => ''));
            }*/
            if (!empty($sitename)) {
                $pageTitle = str_replace(array($sitename.' - ', $sitename.$sitenameSep), array('', ''), $pageTitle);
            }
        }

        if ($preferTitle) {
            $pageTitle = trim($pageTitle);

            // Prevent name duplicity if set to
            if ($preventDupl && strcmp($pageTitle, trim($sitename)) == 0) {
                $pageTitle = '';
            }

            if (empty($pageTitle)) $sitenameSep = '';

            if ($useSitename == _COM_SEF_SITENAME_BEFORE && $sitename) {
                $pageTitle = $sitename . $sitenameSep . $pageTitle;
            }
            elseif ($useSitename == _COM_SEF_SITENAME_AFTER && $sitename) {
                $pageTitle .= $sitenameSep . $sitename;
            }

            $pageTitleEscaped = str_replace('"', '&quot;', $pageTitle);

            // set page title and (optionally) meta title tag
            if ($pageTitle) {
                // Joomla escapes the title automatically
                $document->setTitle($pageTitle);

                // set title meta tag (if enabled in global Joomla config)
                if ($useMetaTitle) {
                    // but we need to use escaped string for meta data
                    $document->setMetaData('title', $pageTitleEscaped);
                }
            }
        }
    }

    function _checkBaseHref()
    {
        $sefConfig =& SEFConfig::getConfig();

        $checkBaseHref = $sefConfig->check_base_href;

        // now we can set base href
        $document =& JFactory::getDocument();
        if ($checkBaseHref == _COM_SEF_BASE_HOMEPAGE) {
            $document->setBase(JURI::base());
        }
        elseif ($checkBaseHref == _COM_SEF_BASE_CURRENT) {
            $document->setBase(JURI::current());
        }
        elseif ($checkBaseHref == _COM_SEF_BASE_NONE) {
            $document->setBase('');
        }
        else return;
    }

    function _noFollow(&$text)
    {
        $sefConfig =& SEFConfig::getConfig();

        // Early checks
        if (!$sefConfig->external_nofollow) {
            return;
        }
        if (JString::strpos($text, 'href="') === false) {
            return;
        }

        // Get all the links
        $matches = array();
        if (!preg_match_all('/<a\s.*href=["\']([^"\']*)["\'][^>]*>/iU', $text, $matches)) {
            return;
        }

        // Combine arrays - as side effect removes duplicities :)
        $hrefs = array_combine($matches[0], $matches[1]);
        $replaceFrom = array();
        $replaceTo = array();

        // Loop through links
        $keys = array_keys($hrefs);
        $localUri =& JURI::getInstance();
        $localHost = $localUri->getHost();
        foreach ($keys as $key) {
            $href = $hrefs[$key];

            // Check if there already is a nofollow tag
            if (JString::strpos($key, 'rel="nofollow"') !== false || JString::strpos($key, "rel='nofollow'") !== false) {
                continue;
            }

            // Parse the URL
            $url = parse_url($href);

            if (!isset($url['host']) || ($url['host'] == $localHost)) {
                continue;
            }

            // Add the nofollow tag
            $to = substr($key, 0, -1) . ' rel="nofollow">';

            $replaceFrom[] = $key;
            $replaceTo[] = $to;
        }

        if (count($replaceFrom) > 0) {
            // Replace the links
            $text = str_replace($replaceFrom, $replaceTo, $text);
        }
    }

    function _wordLinks(&$text)
    {
        $sefConfig =& SEFConfig::getConfig();

        // Early check
        if (!$sefConfig->internal_enable) {
            return;
        }

        $rel = '';
        if ($sefConfig->internal_nofollow) {
            $rel = ' rel="nofollow"';
        }

        $target = '';
        if ($sefConfig->internal_newwindow) {
            $target = ' target="_blank"';
        }

        // Load all the linked words
        $db =& JFactory::getDBO();
        $query = "SELECT `w`.`word`, `u`.`sefurl`, `u`.`metatitle` FROM `#__sefwords` AS `w` INNER JOIN `#__sefurlword_xref` AS `x` ON `w`.`id` = `x`.`word` INNER JOIN `#__sefurls` AS `u` ON `u`.`id` = `x`.`url`";
        $db->setQuery($query);
        $words = $db->loadObjectList();

        // Any words?
        if (empty($words)) {
            return;
        }

        // Create associative array of words and links
        $list = array();
        foreach ($words as $word) {
            if (!isset($list[$word->word])) {
                $list[$word->word] = array();
            }
            $url = new stdClass();
            $url->link = $word->sefurl;
            $url->title = $word->metatitle;
            $list[$word->word][] = $url;
        }

        // Replace all the words with links
        foreach ($list as $word => $urls) {
            if (count($urls) == 1) {
                // Only a regular link
                $replace = '<a href="/'.$urls[0]->link.'"'.$target.$rel.'>$4</a>';
            }
            else {
                // Multiple links
                $replace = '<a href="javascript:void(0);" onclick="jsShowLinks(this, \''.$word.'\');">$4</a>';

                // Add div for the word
                if (!isset($this->linksDivs[$word])) {
                    $this->linksDivs[$word] = $urls;
                }
            }

            // Replace the word
            $regEx = '\'(?!((<.*?)|(<a.*?)))(\b'.$word.'\b)(?!(([^<>]*?)>)|([^>]*?</a>))\'si';
            $text = preg_replace($regEx, $replace, $text, $sefConfig->internal_maxlinks);
        }
    }
    
    function _generateScript()
    {
        $sefConfig =& SEFConfig::getConfig();

        // Early check
        if (!$sefConfig->internal_enable) {
            return;
        }

        $rel = '';
        if ($sefConfig->internal_nofollow) {
            $rel = ' rel="nofollow"';
        }

        $target = '';
        if ($sefConfig->internal_newwindow) {
            $target = ' target="_blank"';
        }

        if (count($this->linksDivs) == 0) {
            // Nothing to be done
            return;
        }
        
        // Add the needed JS and CSS
        $document =& JFactory::getDocument();
        $document->addScript(JURI::root().'components/com_sef/assets/jsLinks.js');
        $document->addStyleSheet(JURI::root().'components/com_sef/assets/jsLinks.css');
        
        // Create the script
        $script = '
jsOnDomReady(jsInitLinks);
function jsInitLinks() {
var div = null;
';
        
        foreach ($this->linksDivs as $word => $urls) {
            $script .= '
div = document.createElement(\'div\');
div.style.display = \'none\';
div.style.position = \'absolute\';
div.className = \'jsLinks\';
div.id = \'jsLinks_'.$word.'\';
div.onmouseout = function(ev) { jsHideDiv(ev, this); };
div.innerHTML = \'<div class="jsWord">'.$word.'</div>';

            foreach ($urls as $url) {
                $title = empty($url->title) ? $url->link : str_replace("'", "\'", $url->title);
                $script .= '<div class="jsLink"><a href="'.$url->link.'"'.$target.$rel.'>'.$title.'</a></div>';
            }
            $script .= '\';';
            $script .= '
document.body.appendChild(div);
';
        }
        
        $script .= '}';
        $document->addScriptDeclaration($script);
    }
}
?>